package org.bud.util;

import com.aliyun.auth.credentials.Credential;
import com.aliyun.auth.credentials.provider.StaticCredentialProvider;
import com.aliyun.sdk.gateway.pop.models.Request;
import com.aliyun.sdk.gateway.pop.models.Response;
import com.aliyun.sdk.service.ocr_api20210707.AsyncClient;
import com.aliyun.sdk.service.ocr_api20210707.models.RecognizeBasicRequest;
import com.aliyun.sdk.service.ocr_api20210707.models.RecognizeBasicResponse;
import com.aliyun.sdk.service.ocr_api20210707.models.RecognizeIdcardRequest;
import com.aliyun.sdk.service.ocr_api20210707.models.RecognizeIdcardResponse;
import darabonba.core.client.ClientOverrideConfiguration;

import java.util.concurrent.CompletableFuture;
import java.util.function.Supplier;
import java.util.function.UnaryOperator;

/**
 * @author shaun
 * @date 2025/3/21
 * @instruction
 */
public abstract class OcrUtil {
    private static final String OCR_ACCESS_KEY_ID = "OCR_ACCESS_KEY_ID";
    private static final String OCR_ACCESS_KEY_SECRET = "OCR_ACCESS_KEY_SECRET";

    public static <I extends Request,O extends Response> O doOcr(String accessKeyId, String accessKeySecret, String requestType, Supplier<I> requestSupplier) {
        StaticCredentialProvider provider = StaticCredentialProvider.create(Credential.builder()
                .accessKeyId(accessKeyId)
                .accessKeySecret(accessKeySecret)
                .build());
        AsyncClient client = AsyncClient.builder()
                .credentialsProvider(provider)
                .overrideConfiguration(
                        ClientOverrideConfiguration.create()
                                // Endpoint 请参考 https://api.aliyun.com/product/ocr-api
                                .setEndpointOverride("ocr-api.cn-hangzhou.aliyuncs.com")
                        //.setConnectTimeout(Duration.ofSeconds(30))
                )
                .build();
        try {
            // Synchronously get the return value of the API request
            I recognizeRequest = requestSupplier.get();
            // Asynchronously get the return value of the API request
            CompletableFuture<O> response = (CompletableFuture<O>)client
                    .getClass().getMethod(requestType,recognizeRequest.getClass())
                    .invoke(client,recognizeRequest);
            return response.get();
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            client.close();
        }
    }

    public static <I extends Request,O extends Response> O doOcr(String requestType, Supplier<I> requestSupplier) {
        return doOcr(System.getenv(OCR_ACCESS_KEY_ID),System.getenv(OCR_ACCESS_KEY_SECRET),requestType,requestSupplier);
    }

    public static RecognizeBasicResponse recognizeBasic(UnaryOperator<RecognizeBasicRequest.Builder> builderAppend){
        return OcrUtil.doOcr(
                "recognizeBasic",
                () -> builderAppend.apply(RecognizeBasicRequest.builder().needRotate(false))
                        .build()
        );
    }

    public static RecognizeIdcardResponse recognizeIdcard(UnaryOperator<RecognizeIdcardRequest.Builder> builderAppend){
        return OcrUtil.doOcr(
                "recognizeIdcard",
                () -> builderAppend.apply(RecognizeIdcardRequest.builder())
                        .build()
        );
    }

}
